Population Displacement in Chicago Communities

In the last decade, underrepresented minority populations in Chicago have been increasingly relegated to lower income areas in the South and West of the City.

all_demos_range <- readRDS(here::here("data", "range_demos_chi_proj.Rda"))
wards.2015 <- readRDS(here::here("data", "wards2015_sf.Rda"))

ward_range <- st_intersection(wards.2015, all_demos_range)

# plot intersection of Census tracts with chicago wards
# st_intersection(wards.2015, all_demos_range) %>%
ward_range %>% filter((predominant_race == "Latinx") & (id != 2015)) %>%
ggplot() +
  # outline tracts based on predominant race based on Census, shaded by median Income for tract
  geom_sf(aes(fill=below_poverty_pct), lwd = 2, color="#6d7d53") +

  scale_fill_gradient(low = "#dae0e2", high="#2d4f5a") +
  
  # outline Chicago wards over data
  geom_sf(data = wards.2015, color="#292929", lwd = 1, fill=NA) +

  coord_sf(datum = NA) +
  theme_map_modest() + 
  theme(
        plot.title = element_text(face = "bold", hjust="0.5", family = "Ledger", size=rel(2.5)),
        plot.subtitle = element_text(margin = unit(c(0, 0, 1, 0), "lines"), size=rel(2)),
        plot.caption = element_text(hjust=1, size=rel(1.75)),
        strip.text.x = element_text(family="Ledger", size=rel(2.25)),
        legend.position = "bottom",
        legend.box = "vertical",
        legend.title = element_text(size=rel(2), family = "Ledger"),
        legend.text = element_text(size=rel(1.1)),
        legend.key.size = unit(45, "pt"),
        panel.spacing = unit(1, "lines"),
        plot.margin = unit(c(2,4,2,2),"lines")
        ) +
  facet_wrap(~ id) + 
  # guides(fill = guide_colourbar(title.position="top", title.hjust = 0.5)) + 
  labs(alpha = "Median Income", color="Predominant Race", title="Latinx Populations in Chicago Pushed to South, West Neighborhoods", caption="Data Source: U.S. Census Bureau", 
       subtitle = "Chicago racial and ethnic group movement by census tract since 2012 (5 year averages) show that Latinx communities are being\ndisplaced from the city center.", fill="Tract Percentage Below Federal Poverty Line") 

ward_range %>% filter((predominant_race == "Black") & (id != 2015)) %>%
ggplot() +
  # outline tracts based on predominant race based on Census, shaded by median Income for tract
  # geom_sf(aes(alpha=below_poverty_pct), lwd = 0, fill=get_dt_cols("ocean")) +

  geom_sf(aes(fill=below_poverty_pct), lwd = 2, color="#9d8e64") +
  # scale_alpha(range = c(0.15, 1)) +
  scale_fill_gradient(low = "#dae0e2", high="#2d4f5a") +
  # outline Chicago wards over data
  geom_sf(data = wards.2015, color="#292929", lwd = 1, fill=NA) +
  coord_sf(datum = NA) +
  theme_map_modest() + 
  theme(
        plot.title = element_text(face = "bold", hjust="0.5", family = "Ledger", size=rel(2.5)),
        plot.subtitle = element_text(margin = unit(c(0, 0, 1, 0), "lines"), size=rel(2)),
        plot.caption = element_text(hjust=1, size=rel(1.75)),
        strip.text.x = element_text(family="Ledger", size=rel(2.25)),
        legend.position = "bottom",
        legend.box = "vertical",
        legend.title = element_text(size=rel(2), family = "Ledger"),
        legend.text = element_text(size=rel(1.1)),
        legend.key.size = unit(45, "pt"),
        panel.spacing = unit(1, "lines"),
        plot.margin = unit(c(2,4,2,2),"lines")
        ) +
  facet_wrap(~ id) +
  # guides(fill = guide_colourbar(title.position="top", title.hjust = 0.5)) + 
  labs(alpha = "Median Income", color="Predominant Race", title="In Contrast, Black Communities Stay in Place in Increasingly Poor Neighborhoods ", caption="Data Source: U.S. Census Bureau", 
       subtitle = "Black communities are not pushed out of their neighborhoods, however, the percentage of residents below the federal poverty line\nin predominantly Black tracts has increased city-wide.", fill="Tract Percentage Below Federal Poverty Line") 

Business Activity across Chicago Areas

all_wards_all_dates <-  readRDS(here::here("data", "all_wards_all_dates.Rda"))

allDatesCount.df <- all_wards_all_dates %>% expand(SIDE_CLEAN, WARD, `APPLICATION TYPE`, count_date) %>% 
 full_join(all_wards_all_dates) %>%  arrange(SIDE_CLEAN, WARD, `APPLICATION TYPE`, count_date) %>% 
  mutate(
    activity_wk = lubridate::as_date(
      cut(count_date, breaks = "week", start.on.monday = FALSE, origin = lubridate::origin)),
   activity_month = lubridate::as_date(
      cut(count_date, breaks = "month", start.on.monday = FALSE, origin = lubridate::origin)),
   activity_qtr = lubridate::as_date(
      cut(count_date, breaks = "quarter", start.on.monday = FALSE, origin = lubridate::origin)) 
   )


library(lemon)
allDatesCount.df %>% 
  filter(`APPLICATION TYPE` %in% c("ISSUE", "RENEW")) %>% group_by(SIDE, activity_qtr, `APPLICATION TYPE`) %>% 
  summarise(active_businesses = sum(active_businesses)) %>% 
  arrange(activity_qtr, desc(active_businesses), SIDE) %>%
 mutate(SIDE_CLEAN = factor(SIDE,levels = rev(unique(SIDE))),
        SIDE_CLEAN = ifelse(SIDE_CLEAN == "Far Southwest", "Far Southwest Side", 
                     ifelse(SIDE_CLEAN == "Far Southeast", "Far Southeast Side",
                     SIDE_CLEAN))) %>%
              ggplot(aes(x=activity_qtr, y=active_businesses)) +   
  geom_bar(aes(x=activity_qtr, y=active_businesses, fill=`APPLICATION TYPE`), stat = "identity", position="dodge") +
  scale_fill_dt(labels=c("    Newly Issued Licenses    ", "    License Renewals    ")) +
  # geom_text(aes(label=active_businesses), 
  #           size = 3, position = position_stack(vjust = 0.5), color="white") +
  scale_y_continuous(labels = scales::comma) +
  scale_x_date(date_labels = "%b %y", 
                date_breaks = "1 year", limits = c(ymd("2012-01-01"), ymd("2018-12-31"))) +
  theme_modest() + 
  theme(
        legend.direction = "horizontal",
        legend.key.size = unit(25, "pt"),
        legend.title = element_blank(),
        panel.grid.minor = element_blank(),
        panel.grid.major.x = element_blank(),
        panel.spacing = unit(2, "lines"),
        strip.text = element_text(family="Ledger", size=rel(1.2)),
        axis.title.y = element_text(size=rel(1.5), margin=unit(c(0,0,2,2), "lines"), angle=90, family="Ledger"),
        axis.text.y = element_text(size=rel(1), margin=unit(c(0,0,2,2), "lines")),
        axis.text.x = element_text(hjust = 0, angle=-45),
        legend.position = "bottom",
        axis.title.x = element_blank(),
        plot.margin = unit(c(2,4,2,2),"lines")) + 
  facet_rep_wrap(~ SIDE_CLEAN, repeat.tick.labels=TRUE) +
      labs(y="Number of Business Licenses Issued or Renewed", 
           colour="Chicago Council Ward", 
           caption="Data Source: Chicago Open Data Portal",  
           title="New Business Never Returns to Far Southeast and Far Southwest Post-Recession", 
           subtitle = "Steady decline in new business entry post-recession in Chicago areas with lowest economic activity pre-recession", fill="Chicago Area")  

  # annotate("text", x=lubridate::ymd("2013-01-01"), y = 850000, label="Business renewals dipping in 2013, were balanced by spikes in new business due to EDGE tax credits.")

Immediately post-recession in 2013, the amount of Economic Development for a Growing Economy (EDGE) tax credits granted by Illinois nearly doubled from the prior year, causing a brief spike in new business license issuances for every area of the city beyond Central (Loop area), which has experienced fairly constant new business entry since the recession. Thus far, only the West Side of Chicago is approaching 2012 levels of new business, with most other areas of the city remaining fairly constant after EDGE excitement tapered off. In the Far Southeast and Far Southwest Sides, where economic activity (in terms of number of active businesses) was about half the next lowest areas even pre-taper, one must wonder how much growth a neighborhood can experience with a rate of new business entry that has hovered around 500 businesses operating on newly-issued licenses for months. For contrast, the mean number of quarterly new licenses issued in the Central area of the city is just under 700,000, and the mean number of quarterly licenses issued in the Northwest Side is just over 85,000.

Mapping Chicago’s Forgotten Economies

# filter for business license issuances and renewals, and create a monthly count
bus_licenses %>% filter(!is.na(WARD), active==1,  activity_date >= mdy("1/1/2012")) %>%
  group_by(activity_month, activity_yr, WARD, SIDE) %>% 
  summarise(business_count = n()) %>% group_by(WARD, SIDE) %>% arrange(desc(business_count)) %>% 
  
  # plot boxplot of median monthly issuances and renewals for each ward
  ggplot(aes(x=reorder(reorder(reorder(SIDE, business_count, FUN = median),WARD),business_count, FUN=median), y=business_count)) + 
  # add comparison line for lowest levels of montly ward business activity
  geom_hline(yintercept=25, linetype = "dotted") +
  # draw boxplots with color and order determined by Chicago Side area
  geom_boxplot(aes(group=reorder(as.factor(WARD), SIDE), fill=as.factor(SIDE)), show.legend = FALSE) + 
  scale_fill_dt() +
  
  # limit scale to 750, (one Loop ward's outliers extend ~1000 above other wards)
  # still very clearly the highest even without all outliers visible
  scale_y_continuous(breaks = sort(c(seq(0, 750, 150), 25)), limits = c(0, 750), 
                     minor_breaks = seq(0 , 750, 75)) +
  scale_x_discrete(breaks=unique(bus_licenses$SIDE), 
    labels=addline_format(as.factor(unique(bus_licenses$SIDE))) ) +
  labs(x="Chicago Council Ward", y="Average Monthly Business Count", caption="Data Source: Chicago Open Data Portal", title="Least New & Surviving Businesses in Far South, Southwest Wards for 5+ Years", subtitle="Since 2012, Far South wards average 26 or less monthly business license issuances and renewals",fill="Chicago Area") + 
  theme_modest() +
  theme(
        panel.grid.major.x = element_blank(),
        axis.ticks =  element_blank(),
        axis.title.x = element_blank(),
        axis.text.x = element_text( family="Ledger", size=rel(1)),
        axis.text.y = element_text( margin=unit(c(0,2,2,2), "lines"), size=rel(1)),
        axis.title.y = element_text(margin=unit(c(0,0,2,2), "lines"), size=rel(1.2), angle = 90, family = "Ledger"),
        plot.caption = element_text(hjust=1)
        ) +
  annotate("text", x = 7 , y= 390, label="Most West Side business\noccurs in Wards 2 and 27,\nwhich border the Loop.", size=rel(4)) +
  annotate("text", x = 8.9 , y= 745, label="The Central area is comprised\nof Ward 42, the Loop area.", size=rel(4)) +
  annotate("text", x = 5 , y= 335, label="South Side business activity\nis concentrated in Kenwood,\n Fuller Park areas bordering\nthe University of Chicago.", size=rel(4)) +
  annotate("text", x = 3 , y= 305, label="Ward 12 on the Southwest\nSide bordering Chinatown is\ncharacterized by higher rates\nof business activity than\nits neighbors.", size=rel(4)) 

Exploring Voter Activation in Deinvested Wards

# read in turnout and change in turnout by Chicago ward and Chciago Side
  turnoutSides <-  readRDS(here::here("data", "sides_turnout.Rda"))
  turnoutDiff <-  readRDS(here::here("data", "wards_turnout.Rda"))
  
  # turnoutDiff %>% group_by(SIDE, WARD) %>% summarise(z = max(TURNOUT)) %>% filter(SIDE == "Far Southwest")
  
  # plot average turnout in 2011 and 2015 for each Chicago Side
  ggplot(turnoutSides, aes(x=as.factor(YEAR), y=TURNOUT, group=as.factor(SIDE))) + 
  geom_line(aes(colour=SIDE), size=1.5, show.legend = FALSE) +
  # geom_line(data = filter(turnoutSides, (DIFFERENCE > -0)||(is.na(DIFFERENCE))), aes(colour=SIDE), size=1.5, show.legend=FALSE) +
  scale_color_dt() + 
    
  # add lines for distribution within each Side at Ward level
  geom_line(data = turnoutDiff, aes(group=as.factor(WARD), color=SIDE), size=0.5, alpha=0.35, show.legend = FALSE) +
  
  # label each Side's values in line graphs for both 2011 and 2015
  geom_label_repel(data = turnoutSides %>% filter(YEAR == 2011), 
            aes(label = paste0(SIDE, " - ", TURNOUT, "%"), color = SIDE),
            fill=NA,
            hjust = "left",
            nudge_x = -.15,
            force=6,
            direction = "y",
            xlim= c(-0.5,.965),
            fontface = "bold",
            label.size = 0,
            point.padding   = 0.75,
            size = rel(5),
            show.legend = FALSE,
            family="Ledger") +
  geom_label_repel(data = turnoutSides %>% filter(YEAR == 2015),
            aes(label = paste0(SIDE, " - ", TURNOUT, "%"), color = SIDE),
            fill=NA,
            hjust = "right",
            nudge_x = .25,
            force = 5,
            direction = "y",
            fontface = "bold",
            point.padding   = 0.75,
            xlim=c(2.05,3),
            label.size = 0,
            size = rel(5),
            show.legend = FALSE,
            family="Ledger") +
  # move x-axis text to top of graph
  scale_x_discrete(position = "top") +
   # coord_cartesian(ylim=c(23.5, 60)) +
  theme_modest() + 
  theme(axis.text.x.top = element_text(size=rel(1.25), vjust = -8, face="bold", family="Ledger"),
          axis.title.y = element_blank(),
          axis.title.x = element_blank(),
          axis.text.y = element_blank(),
          panel.grid.minor=element_blank(),
          panel.grid.major=element_blank()
          # plot.title = element_text(size=rel(1.5)),
          # plot.subtitle = element_text(hjust=0.35)
        ) +
       
  labs(title="Amid City-Wide Turnout Dropoff, Significantly Higher Voter Activation in Far Southwest Side", 
         subtitle="Voters in the Far Southeast, which has faced de-investment as determined by a number of factors, far exceeded other areas'\nparticipation in the last two City Council elections.", 
         caption="Source: Chicago Board of Election Commissioners", color="Chicago Area") +
  annotate("text",  x = 1, y = 25, label = "*Underlying ward trends visualized\nbehind Side trendlines", size=rel(4)) + 
    annotate("text", x = 0.8, y = 65, label="Ward 19 on the Far Southwest\nSide, which contains the Beverly\nand Morgan Park neighborhoods,\nhad voter turnout of nearly 75%\n in the 2011 City Council Election.", size=rel(4), hjust=0, color=get_dt_cols("mauve"))